#include "Resource.h"
#include <iostream>
#include <fstream.>
#include <stdlib.h>
#include <string>

using namespace std;

//ctor & dtor
Resource::Resource(){
};
Resource::~Resource(){
};

//inisialisasi
void Resource::initialize(){
	StoreElem storeElem;
	storeElem.name = "dummy";
	storeElem.price = 1;
	storeInfo.push_back(storeElem);
	storeElem.name = CARROT_FRUIT_STRING;
	storeElem.price = CARROT_FRUIT_PRICE;
	storeInfo.push_back(storeElem);
	storeElem.name = TOMATO_FRUIT_STRING;
	storeElem.price = TOMATO_FRUIT_PRICE;
	storeInfo.push_back(storeElem);
	storeElem.name = CHILLI_FRUIT_STRING;
	storeElem.price = CHILLI_FRUIT_PRICE;
	storeInfo.push_back(storeElem);
	storeElem.name = STRAWBERRY_FRUIT_STRING;
	storeElem.price = STRAWBERRY_FRUIT_PRICE;
	storeInfo.push_back(storeElem);
	storeElem.name = MELON_FRUIT_STRING;
	storeElem.price = MELON_FRUIT_PRICE;
	storeInfo.push_back(storeElem);
	storeElem.name = CARROT_FRUIT_STRING;
	storeElem.price = CARROT_SEED_PRICE;
	storeInfo.push_back(storeElem);
	storeElem.name = TOMATO_FRUIT_STRING;
	storeElem.price = TOMATO_SEED_PRICE;
	storeInfo.push_back(storeElem);
	storeElem.name = CHILLI_FRUIT_STRING;
	storeElem.price = CHILLI_SEED_PRICE;
	storeInfo.push_back(storeElem);
	storeElem.name = STRAWBERRY_FRUIT_STRING;
	storeElem.price = STRAWBERRY_SEED_PRICE;
	storeInfo.push_back(storeElem);
	storeElem.name = MELON_FRUIT_STRING;
	storeElem.price = MELON_SEED_PRICE;
	storeInfo.push_back(storeElem);

	itemName.push_back("dummy");
	itemName.push_back(CARROT_FRUIT_STRING);
	itemName.push_back(TOMATO_FRUIT_STRING);
	itemName.push_back(CHILLI_FRUIT_STRING);
	itemName.push_back(STRAWBERRY_FRUIT_STRING);
	itemName.push_back(MELON_FRUIT_STRING);
	itemName.push_back(CARROT_SEED_STRING);
	itemName.push_back(TOMATO_SEED_STRING);
	itemName.push_back(CHILLI_SEED_STRING);
	itemName.push_back(STRAWBERRY_SEED_STRING);
	itemName.push_back(MELON_SEED_STRING);

	itemData.insert(make_pair("carrot",CARROT_SEED_CODE));
	itemData.insert(make_pair("tomato",TOMATO_SEED_CODE));
	itemData.insert(make_pair("melon",MELON_SEED_CODE));
	itemData.insert(make_pair("strawberry",STRAWBERRY_SEED_CODE));
	itemData.insert(make_pair("chilli",CHILLI_SEED_CODE));
};

//ctor singleton
Resource* Resource::instance() {
	static Resource resource;
	return &resource;
}

//mengembalikan daftar harga dan nama barang
StoreInfo Resource::getStoreInfo(){
	return storeInfo;
}

string Resource::getItemName(int x){
	return itemName[x];
}

ItemType Resource::getItemCode(string itemName){
	return (itemData.find(itemName))->second;
}

//Character Machine

void Resource::start()
{
	loadHarpesMun.open(externalFile.c_str());
	adv();
}


void Resource::adv ()
{
	loadHarpesMun.get(CC);
	if 	(!EOF)
	{
		loadHarpesMun.close();
		cout << "File has reached EOF" << endl;
	}
}

void Resource::startWord()
{
    start();
	if 	(!loadHarpesMun)
		{
			loadHarpesMun.close();
			SI.status = STATUS_NULL;
		}
	else
		{
			if  (CC == MARK)
			{
				//EndWord = true;
				cout << "Empty File" << endl;
				SI.status = STATUS_EMPTY;
			}
			else
			{
				//EndWord = false;
				copyWord();
				SI.status = STATUS_FOUND;
			}
		}
}

void Resource::copyWord()
{
    int i;
	while (CC != BLANK)
    {
        SI.PI.name += CC; //mengisi nama player
        adv();
    } //CC = BLANK
	cout << "1" << CC << endl;
    adv(); //CC = MARK
	cout << "2" << CC << endl;
	adv(); //CC = '\n'
	cout << "3" << CC << endl;
	adv(); //CC = Player's current area
	cout << "4" << CC << endl;
	SI.PI.curArea = atoi(&CC);
	advAttrib(); //siap membaca atribut berikutnya

	adv(); //CC = x
	SI.PI.curPos.x = atoi(&CC);
	adv(); //CC = ','
	adv(); //CC = y
	SI.PI.curPos.y = atoi(&CC);
	advAttrib();

	adv(); //CC = curDir
	SI.PI.curDir = atoi(&CC);
	advAttrib();

	adv();
	char timeLeft_temp[2];
	i=0;
	while (CC != BLANK)
	{
		timeLeft_temp[i] = CC;
		i++;
		adv();
	} //CC = BLANK
	SI.PI.timeLeft = atoi(timeLeft_temp);
	adv(); //CC = MARK
	adv(); //CC = '\n'

	adv();
	char day_temp[3];
	i=0;
	while (CC != BLANK)
	{
		day_temp[i] = CC;
		i++;
		adv();
	} //CC = BLANK
	SI.PI.day = atoi(day_temp);
	adv(); //CC = MARK
	adv(); //CC = '\n'

	adv();
	char balance_temp[6]; //duit maksimum 6 digit
	i=0;
    while (CC != BLANK)
    {
        balance_temp[i] = CC; //mengisi player's balance
        i++;
        adv();
    } //CC = BLANK
	SI.PI.balance = atoi(balance_temp);
	cout << "12 " << CC << endl;
    adv(); //CC = MARK
	cout << "13 " << CC << endl;
	adv(); //CC = '\n'
	cout << "14 " << CC << endl;

	for(i=0;i<=2;i++)
	{
	    InventoryElem tono;
	    tono.item = 0;
	    tono.amount = 0;
		adv();
		int j = 0;
		char *item_temp = new char[3];
		while (CC != BLANK){
            item_temp[j] = CC;
            j++;
            adv();
		}
		tono.item = atoi(item_temp); 
		adv(); //CC = ','
		adv();
		j = 0;
		char *amount_temp = new char [3];
		while (CC != BLANK){
            amount_temp[j] = CC;
            j++;
            adv();
        }
		amount_temp[j] = NULL;
		tono.amount = atoi(amount_temp);

		if ((tono.amount!=0) && (tono.item!=0))
            SI.PI.myInventory.push_back(tono);
		
		//advAttrib();
        adv();
        adv();
        delete [] amount_temp ;
        delete [] item_temp ;
	}
	adv(); //CC = '\n'
	adv(); //CC = MARK
	copyDwarf(); //menyalin dwarf
}

void Resource::advAttrib()
{
	adv(); //CC = BLANK
	adv(); //CC = MARK
	adv(); //CC = '\n'
}

void Resource::copyDwarf()
{
	int i;
	for(i=0;i<=2;i++) //pengulangan sejumlah dwarf
	{
	    char * x_temp = new char [2];
	    char * y_temp = new char [2];

		adv();
		SI.ADI[i].type = atoi(&CC);
		advAttrib();

		adv();
		SI.ADI[i].status = atoi(&CC);
		advAttrib();
        int j = 0;
		adv(); //CC = x
            while (CC != BLANK){
                x_temp[j] = CC;
                j++;
                adv();
            }
		x_temp[j]=NULL;
        SI.ADI[i].curPos.x = atoi(x_temp);
		adv(); //CC = ','
		adv(); //CC = y
        j = 0;
            while (CC != BLANK){
                y_temp[j] = CC;
                j++;
                adv();
            }
		y_temp[j] = NULL;
		SI.ADI[i].curPos.y = atoi(y_temp);
		advAttrib();
		SI.ADI[i].curDir = atoi(&CC);
		advAttrib();
		adv(); //CC = MARK
		adv(); //CC = '\n'
		delete [] x_temp;
		delete [] y_temp;
	}
	copyPlant(); //menyalin tanaman
}

void Resource::copyPlant()
{
	int PlantQuantity;
	int i;
	adv();
	PlantQuantity = atoi (&CC);
	advAttrib();
	cout << CC << endl;
	adv(); //CC = MARK
	cout << CC << endl;
	adv(); //CC = '\n'
	cout << PlantQuantity << endl;
	for(i=0; i<PlantQuantity; i++)
	{
		adv();
		SI.AP[i].PT = atoi(&CC);
		advAttrib();
		adv();
		SI.AP[i].HM = atoi(&CC);
		advAttrib();
		adv();
		SI.AP[i].AL = atoi(&CC);
		cout << "hahaha" << CC << endl;
		advAttrib();
		adv(); //CC = x
		SI.AP[i].Position.x = atoi(&CC);
		cout << SI.AP[i].Position.x << endl;
		adv(); //CC = ','
		adv(); //CC = y
		SI.AP[i].Position.y = atoi(&CC);
		cout << SI.AP[i].Position.y << endl;
		advAttrib();
		adv(); //CC = MARK
		adv(); //CC = '\n'
	}

	copyFarm();
}

void Resource::copyFarm()
{
	int i;
	int j;
	//--------------------------------------------------
	adv();	while (CC != MARK)
	{
		adv();
	} //CC = MARK
	adv(); //CC = '\n'
	adv(); //CC = first x
	i = 0;
	while (CC != MARK)
	{
		char * temp_x = new char [2];
		j=0;
		while (CC!=',')
		{
			temp_x[j]=CC;
			j++;
			adv();
		}
		temp_x[j] = NULL;
		SI.FP.plantable[i].x = atoi(temp_x);
		
		char * temp_y = new char[2];
		j=0;
		adv();
		while (CC!=BLANK)
		{
			temp_y[j]=CC;
			j++;
			adv();
		}
		temp_y[j] = NULL;
		SI.FP.plantable[i].y = atoi(temp_y);
		adv();
		adv();
		i++;
		adv(); //CC = next x, bisa MARK
		delete [] temp_x;
		delete [] temp_y;
	} //CC = MARK
	//--------------------------------------------------
	adv(); //CC = '\n'
	while (CC != MARK)
	{
		adv();
	} //CC = MARK
	adv(); //CC = '\n'
	adv(); //CC = first x
	i = 0;
	while (CC != MARK)
	{
		char * temp_x = new char [2];
		j=0;
		while (CC!=',')
		{
			temp_x[j]=CC;
			j++;
			adv();
		}
		temp_x[j] = NULL;
		SI.FP.plowed[i].x = atoi(temp_x);
		
		char * temp_y = new char[2];
		j=0;
		adv();
		while (CC!=BLANK)
		{
			temp_y[j]=CC;
			j++;
			adv();
		}
		temp_y[j] = NULL;
		SI.FP.plowed[i].y = atoi(temp_y);
		adv();
		adv();
		i++;
		adv(); //CC = next x, bisa MARK
		cout << "x: "<<temp_x << "y: "<<temp_y << endl;
		delete [] temp_x;
		delete [] temp_y; 
	} //CC = MARK
	//--------------------------------------------------
	adv(); //CC = '\n'
	while (CC != MARK)
	{
		adv();
	} //CC = MARK
	adv(); //CC = '\n'
	adv(); //CC = first x
	i = 0;
	while (CC != MARK)
	{
		char * temp_x = new char [2];
		j=0;
		while (CC!=',')
		{
			temp_x[j]=CC;
			j++;
			adv();
		}
		temp_x[j] = NULL;
		SI.FP.watered[i].x = atoi(temp_x);
		
		char * temp_y = new char[2];
		j=0;
		adv();
		while (CC!=BLANK)
		{
			temp_y[j]=CC;
			j++;
			adv();
		}
		temp_y[j] = NULL;
		SI.FP.watered[i].y = atoi(temp_y);
		adv();
		adv();
		i++;
		adv(); //CC = next x, bisa MARK
		cout << "x: "<<temp_x << "y: "<<temp_y << endl;
		delete [] temp_x;
		delete [] temp_y; 
	} //CC = MARK
	//--------------------------------------------------
	adv(); //CC = '\n'
	while (CC != MARK)
	{
		adv();
	} //CC = MARK
	adv(); //CC = '\n'
	adv(); //CC = first x
	i = 0;
	while (CC != MARK)
	{
		char * temp_x = new char [2];
		j=0;
		while (CC!=',')
		{
			temp_x[j]=CC;
			j++;
			adv();
		}
		temp_x[j] = NULL;
		SI.FP.noacc[i].x = atoi(temp_x);
		
		char * temp_y = new char[2];
		j=0;
		adv();
		while (CC!=BLANK)
		{
			temp_y[j]=CC;
			j++;
			adv();
		}
		temp_y[j] = NULL;
		SI.FP.noacc[i].y = atoi(temp_y);
		adv();
		adv();
		i++;
		adv(); //CC = next x, bisa MARK
		cout << "x: "<<temp_x << "y: "<<temp_y << endl;
		delete [] temp_x;
		delete [] temp_y; 
	} //CC = MARK
	loadHarpesMun.close();
}

SaveInfo Resource::loadGame(string s)
{
    externalFile = s;
	startWord();
	return SI;
}

#include <stdio.h>
//pake library C, masih belum sesuai yang diinginkan :(

/*string Resource::intToString (int number)
{
	string ss;
	ss << number;
	return ss.str();
}*/
void Resource::saveGame(SaveInfo SI)
{
	int i;
	saveHarpesMun.open((SI.PI.name+SAVE_FILE_EXTENSION).c_str());
	if 	(!saveHarpesMun)
	{
		saveHarpesMun.close();
	}
	saveHarpesMun << SI.PI.name << " #" << endl;
	saveHarpesMun << SI.PI.curArea << " #" << endl;
	saveHarpesMun << SI.PI.curPos.x << "," << SI.PI.curPos.y << " #"<< endl;
	saveHarpesMun << SI.PI.curDir << " #" << endl;
	saveHarpesMun << SI.PI.timeLeft << " #" << endl;
	saveHarpesMun << SI.PI.day << " #" << endl;
	saveHarpesMun << SI.PI.balance << " #" << endl;

	for (i=0;i<=2;i++)
	{
		if(i<SI.PI.myInventory.size())
            saveHarpesMun << SI.PI.myInventory[i].item << " ," << SI.PI.myInventory[i].amount << " #" << endl;
        else
            saveHarpesMun << "0 ,0 #" << endl;
	}
	saveHarpesMun << "#" << endl;

	for (i=0;i<=2;i++)
	{
		saveHarpesMun << SI.ADI[i].type << " #" << endl;
		saveHarpesMun << SI.ADI[i].status << " #" << endl;
		saveHarpesMun << SI.ADI[i].curPos.x << " ," << SI.ADI[i].curPos.y << " #" <<endl;
		saveHarpesMun << SI.ADI[i].curDir << " #" << endl;
		saveHarpesMun << "#" << endl;
	}
	saveHarpesMun << countPlant(SI) << " #" << endl;
	saveHarpesMun << "#" << endl;
	for (i=0;i<countPlant(SI);i++)
	{
		saveHarpesMun << SI.AP[i].PT << " #" << endl;
		saveHarpesMun << SI.AP[i].HM << " #" << endl;
		saveHarpesMun << SI.AP[i].AL << " #" << endl;
		saveHarpesMun << SI.AP[i].Position.x << "," << SI.AP[i].Position.y << " #" << endl;
		saveHarpesMun << "#" << endl;
	}

	saveHarpesMun << "Plantable #" << endl;
	for (i=0;i<countPlantable(SI);i++)
	{
		saveHarpesMun << SI.FP.plantable[i].x << "," << SI.FP.plantable[i].y << " #" << endl;
	}
	saveHarpesMun << "#" << endl;

	saveHarpesMun << "Plowed #" << endl;
	for (i=0;i<countPlowed(SI);i++)
	{
		saveHarpesMun << SI.FP.plowed[i].x << "," << SI.FP.plowed[i].y << " #" << endl;
	}
	saveHarpesMun << "#" << endl;

	saveHarpesMun << "Watered #" << endl;
	for (i=0;i<countWatered(SI);i++)
	{
		saveHarpesMun << SI.FP.watered[i].x << "," << SI.FP.watered[i].y << " #" << endl;
	}
	saveHarpesMun << "#" << endl;

	saveHarpesMun << "No Access #" << endl;
	i = 0;
	while((i<121)&&(SI.FP.noacc[i].x!=NULL)){
	saveHarpesMun << SI.FP.noacc[i].x << "," << SI.FP.noacc[i].y << " #" << endl;
	i++;
	}
	saveHarpesMun << "#";

	saveHarpesMun.close();
}


int Resource::countPlant(SaveInfo SI)
{
	int i=0;
	while (SI.AP[i].PT != NULL)
	{
		i++;
	}
	return i;
}

int Resource::countPlantable(SaveInfo SI)
{
	int i=0;
	while (SI.FP.plantable[i].x)
	{
		i++;
	}
	return i;
}

int Resource::countPlowed(SaveInfo SI)
{
	int i=0;
	while (SI.FP.plowed[i].x)
	{
		i++;
	}
	return i;
}

int Resource::countWatered(SaveInfo SI)
{
	int i=0;
	while (SI.FP.watered[i].x)
	{
		i++;
	}
	return i;
}
